# B站 千峰Python 2019教程700集的259-260，分页器、验证码绘制及验证
from flask import Flask, make_response, session, render_template, request, jsonify
from io import BytesIO
import random
import string
from PIL import Image, ImageFont, ImageDraw, ImageFilter

# pip install pillow
app = Flask(__name__)
app.config['SECRET_KEY'] = "*)asdfasd&fsadffasdf(^(#$#8423!#"
app.debug = True


class imageCode():
    '''    验证码处理    '''

    def rndColor(self):
        '''随机颜色'''
        return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

    def geneText(self):
        '''生成4位验证码'''
        return ''.join(random.sample(string.ascii_letters + string.digits, 4))  # ascii_letters是生成所有字母 digits是生成所有数字0-9

    def drawLines(self, draw, num, width, height):
        '''划线'''
        for num in range(num):
            x1 = random.randint(0, width / 2)
            y1 = random.randint(0, height / 2)
            x2 = random.randint(0, width)
            y2 = random.randint(height / 2, height)
            draw.line(((x1, y1), (x2, y2)), fill='black', width=1)

    def getVerifyCode(self):
        '''生成验证码图形'''
        code = self.geneText()
        # 图片大小120×50
        width, height = 120, 50
        # 新图片对象
        im = Image.new('RGB', (width, height), 'white')
        # 字体
        font = ImageFont.truetype('app/static/arial.ttf', 40)
        # draw对象
        draw = ImageDraw.Draw(im)
        # 绘制字符串
        for item in range(4):
            draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),
                      text=code[item], fill=self.rndColor(), font=font)
        # 划线
        self.drawLines(draw, 2, width, height)
        return im, code

    def getImgCode(self):
        """这里我们采用讲图片转换成二进制的形式，讲图片传送到前端，并且在这个返回值的头部，需要标明这是一个图片。
        　　将验证码字符串储存在session中，是为了一会在登录的时候，进行验证码验证。"""
        image, code = self.getVerifyCode()
        # 图片以二进制形式写入
        buf = BytesIO()
        image.save(buf, 'jpeg')
        buf_str = buf.getvalue()
        # 把buf_str作为response返回前端，并设置首部字段
        response = make_response(buf_str)
        response.headers['Content-Type'] = 'image/gif'
        # 将验证码字符串储存在session中
        session['imageCode'] = code
        return response


# html 使用
#     <img src="{{ url_for('imgCode') }}">
# 验证码
@app.route('/imgCode')
def imgCode():
    return imageCode().getImgCode()


@app.route('/test_login', methods=['GET', 'POST'])
def test_login_code():
    if request.method == 'POST':
        captcha = request.form.get('verify_code').lower()
        if captcha == session['imageCode'].lower():
            return jsonify({'code': 200, 'msg': '登陆成功'})
        else:
            return jsonify({'code': -1, 'msg': '图片验证码错误'})

    return render_template('test_login_code.html')


@app.route('/')
def index():
    return 'Test OK!'


if __name__ == '__main__':
    app.run()

# https://www.cnblogs.com/huxiansheng/p/11987259.html
""" html
<div class="layui-form-item">
    <label class="layui-icon layui-icon-vercode" for="captcha"></label>
    <input type="text" name="captcha" lay-verify="required|captcha" placeholder="图形验证码" autocomplete="off"
           class="layui-input verification captcha" value="">
    <div class="captcha-img">
        <img id="verify_code" class="verify_code" src="/api/imgCode" onclick="this.src='/api/imgCode?'+ Math.random()">
    </div>
</div>
"""
""" js
// 进行登录操作
            form.on('submit(login)', function (data) {
                console.log(data.elem);
                var form_data = data.field;
                //加密成md5
                form_data.password=$.md5(form_data.password);
                $.ajax({
                    url: "{{ url_for('api.api_login') }}",
                    data: form_data,
                    dataType: 'json',
                    type: 'post',
                    success: function (data) {
                        if (data['code'] == 0) {
                            location.href = "{{ url_for('home.homes') }}";
                        } else {
                            //登录失败则刷新图片验证码
                            var tagImg = document.getElementById('verify_code');
                            tagImg.src='/api/imgCode?'+ Math.random();
                            console.log(data['msg']);
                            layer.msg(data['msg']);
                        }
                    }
                });
                return false;
            });
"""
